require("coxpcall")
require("cosmo")
require'zdc.nodeapi'
local actutil=require("zwsapi.actions.util")
local util = require("zwsapi.util")
local html_forms = require("zwsapi.html_forms")
module(..., package.seeall)
actions={}

-----------------------------------------------------------------------------
-- Shows the list of registered users
-----------------------------------------------------------------------------
function actions.show_users(user,dal,node,act,request)

	local TEMPLATE = [[
		<table class="sorttable" width="100%">
		<thead>
			<tr><th>username</th><th>registration time</th></tr>
		</thead>
		$do_users[=[<tr><td><a $link>$username</a></td><td>$time</td></tr>
		]=]
		</table>
	]]
	local users = {}
	for username, record in pairs(node.content.USERS) do
		table.insert(users,
						{ username = username,link = dal:make_link_to_user(username),
							time = dal:format_time(record.creation_time,"%Y/%m/%d %H:%M %z")
						})
	end
	table.sort(users, function(x,y) return x.time < y.time end)

	node.inner_html = cosmo.f(TEMPLATE) {do_users = users}
	return node.wrappers.default(user,dal,node,act,request)
end


-----------------------------------------------------------------------------
-- Shows login form.
-----------------------------------------------------------------------------
function get_login_form(user,dal,node,act,request)
	local post_timestamp = os.time()
	local post_token = dal.auth:Timestamp_token(post_timestamp)
	local field_spec = [[
		--please_login = {4.0, "note"}
		user = {4.1, "text_field", div_class="autofocus"}
		password = {4.2, "password"}
	]]

	if request.params.next then
		field_spec = field_spec .. [[
		next = {4.3, "hidden", no_label = true, div_class="hidden"}
		]]
	end

	local html_for_fields, field_list = html_forms.make_html_form{
		field_spec = field_spec,
		templates  = node.templates, 
		translator = node.translator,
		values	  = {
			user = "",
			password = "",
			next = request.params.next,
		},
		hash_fn	 = function(field_name)
						return dal:hash_field_name(field_name, post_token)
					end
	}

	return cosmo.f(node.templates.LOGIN_FORM){
								html_for_fields = html_for_fields,
								node_name		 = request.params.next or node.name,
								post_fields	  = "user,password,next",
								post_token		= post_token,
								post_timestamp  = post_timestamp,
								action_url		= dal:make_url(dal.config.LOGIN_NODE),
								register_link	= dal:make_url(dal.config.REGISTRATION_NODE),
								if_can_reset_password = cosmo.c(dal.config.REQUIRE_EMAIL_ACTIVATION){
									link = dal:make_link(dal.config.PASSWORD_RESET_NODE or
																	 "@ws/password_reset")
								},
							}
end

function actions.show_login_form(user,dal,node,act,request)
	request.is_indexable = false
	if (request.params.user and request.user) then -- we've just logged in the user
		request.redirect = dal:make_url(node.__id)
		return
	end

	node.inner_html = get_login_form(user,dal,node,act,request)
	return node.wrappers.default(user,dal,node,act,request)
end

function actions.logout_user(user,dal,node,act,request)
	request.is_indexable = false
	request.user = nil
	request.redirect = dal:make_url(request.params.next)
	return
end

function actions.show_chgpwd_form(user,dal,node,act,request)
	-- prepare the timestamp and token
	local post_timestamp = os.time()
	local post_token = dal.auth:Timestamp_token(post_timestamp)

	-- prepare the edit form
	local html_for_fields, field_list = html_forms.make_html_form{
		field_spec =((request.user=='admin' and [[
						username = {1.30, "text_field", div_class="autofocus"}
					]]) or '')..[[
						password = {1.301, "password"}
						new_password = {1.31, "password"}
						new_password_confirm = {1.32, "password"}
					]],
		values={
				username = request.params.username or "",
				new_password = request.params.new_password or "",
				new_password_confirm = request.params.new_password_confirm or "",
				},
		templates  = node.templates, 
		translator = node.translator,
		hash_fn=function(field_name)
					return dal:hash_field_name(field_name, post_token)
				end
	}

	
	node.inner_html = cosmo.f(node.templates.CHANGEPASSWORD){
		html_for_fields = html_for_fields,
		node_name		 = request.node_name,
		post_fields	  = table.concat(field_list,","),
		post_token		= post_token,
		post_timestamp  = post_timestamp,
		action_url		= dal:make_url(node.__id),
		action			 = "submit",
		submitLabel	  = node.translator.translate_key("SUBMIT"),
	}
	return node.wrappers.default(user,dal,node,act,request)
end
function actions.chg_pwd(user,dal,node,act,request)
	function err_msg(err_code)
		request.try_again = true
		node:post_error(node.translator.translate_key(err_code))
	end
	
	local post_ok, err = actutil.check_post_parameters(user,dal,node,act,request)
	if not post_ok then
		err_msg(err)
	else 
		local p = request.params
		if not p.username then p.username=user end
		for message, test in pairs(dal.config.PASSWORD_RULES or {}) do
			if not test(request.params.new_password) then 
				request.try_again = true
				node:post_error(message)
			end
		end

		-- check confirmation password
		if p.new_password ~= p.new_password_confirm then 
			err_msg("TWO_VERSIONS_OF_NEW_PASSWORD_DO_NOT_MATCH")
		end

		-- check that the user name is not taken
		if request.user=='admin' then
			if not dal.auth:Authenticate(dal,request.user,p.password) then
				err_msg("Admin password authenticate fail")
			end
		else
			if  not dal.auth:Authenticate(dal,p.username,p.password) then
				err_msg("Authenticate fail")
			end
		end
	end

	if request.try_again then
		return zdc.nodeapi.getnodeact(dal,node,'show')(user,dal,node,act,request)
	end

	local r,msg=dal.auth:chg_pwd(user,dal,request.params.username, request.params.password,request.params.new_password)
	if r then
		if request.params.username==user then
			request.user, request.auth_token = dal.auth:Authenticate(dal,request.params.username, request.params.new_password)
		end
		node:post_translated_success("SUCCESSFULLY_CHANGE_PASSWORD")
	else
		err_msg(msg)
	end	

	node.inner_html = ""
	return node.wrappers.default(user,dal,node,act,request)
end

